Release 10.1A: OpenEdge Development:
Progress 4GL Handbook


Using the SELF handle to identify an object in a trigger

Now you need to check the SCREEN-VALUE of the field to see whether the user typed anything into it. The reason for this check is that the LEAVE trigger could fire under other circumstances, such as if the user clicked on a button while the cursor was positioned in the field. This action would fire the LEAVE event, but you want to disregard such events unless the user actually entered a value in the field.

But which field? You’re defining the same trigger code for all the fields.

Progress defines another built-in handle that gives you what you need: the SELF handle. Within a trigger block, this handle resolves to the object the trigger has fired for.

To identify a field in a trigger:

  1. Check to see whether the user entered a value using this statement and start a block that is executed only if the user did:
  2.   IF SELF:SCREEN-VALUE NE "" THEN 
      DO: 
    

    It’s important to make this check because the LEAVE trigger fires in many different ways, including clicking on a button while the cursor is in the field. You need to check that the user really entered a value to filter on.

  3. Inside this block, use the list of fill-in field handles to disable them again, now that the user has had a chance to enter a value into one of them:
  4.    DO iField = 1 TO NUM-ENTRIES(cFillIns): 
           ASSIGN hField = WIDGET-HANDLE(ENTRY(iField, cFillins)) 
                  hField:SENSITIVE = NO. 
       END. 
    

    Remember that you defined the cFillIns variable in the Definitions section specifically because you do want its value to be scoped to the whole procedure, so that its value persists between trigger or procedure calls. To remind yourself, and other readers of your code, that a variable like this is scoped to the entire procedure, you can use a naming convention such as putting a g for global on the front of the variable name. Even though such a variable is not actually global to the session, it is global to this procedure, so its scope is worth noting in some way.

  5. Get the handle to the query, along with the current PREPARE-STRING:
  6. ASSIGN hQuery = QUERY CustQuery:HANDLE 
           cPrepare = hQuery:PREPARE-STRING. 
    

    You’re saving off the current PREPARE-STRING before closing and re-preparing the query so that you can restore it later in the block in case the user chooses not to continue with the filtering. There’s a special case you have to deal with here. If the query has not yet been re-prepared dynamically, then the PREPARE-STRING attribute is unable to return the FOR EACH statement used in the original static OPEN QUERY statement. In this case, you just have to set the variable to the default query string:

    /* If the query hasn't been prepared dynamically just restore 
       the original query definition. */ 
    IF cPrepare = ?  THEN   
       cPrepare = "FOR EACH Customer". 
    

  7. Close the query and re-prepare it using its handle and the value the user entered into whichever one of the fill-in fields:
  8.     hQuery:QUERY-CLOSE(). 
        hQuery:QUERY-PREPARE("FOR EACH Customer WHERE " + SELF:NAME + 
                            (IF SELF:DATA-TYPE = "CHARACTER" THEN 
                             " BEGINS " ELSE " = ")                            
                             + QUOTER(SELF:SCREEN-VALUE) + 
                             " BY " + SELF:NAME). 
    

    The QUERY-CLOSE step is actually optional. The QUERY-PREPARE method closes the query automatically.

    Using the DATA-TYPE attribute of the SELF handle, the code identifies the data type of the field the user is filtering on. If the field is CHARACTER, the code builds a query retrieving all Customers where the field value BEGINS with what the user typed in, which is the SELF:SCREEN-VALUE attribute. Otherwise, it retrieves records where the field value is equal to the filter value. You could, of course, set up such a query to filter records in any way that you want. Finally, the FOR EACH statement sorts the record by the filter field, using the SELF:NAME attribute.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095